<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
<title>Serial Communication</title>
<meta name="author" content="Ben Greenstein and Philip Levis" />
<style type="text/css">

/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date: 2009-02-03 23:07:32 $
:version: $Revision: 1.13 $
:copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
*/
body {
  font-family: Times;
  font-size: 16px;
}

.first {
  margin-top: 0 ! important }

.last {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dd {
  margin-bottom: 0.5em }

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning, div.admonition {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title,
div.admonition p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em }

div.footer, div.header {
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 0em 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1 {
  font-family: Arial, sans-serif;
  font-size: 20px;
}

h1.title {
 text-align: center;
 font-size: 32px;
}

h2 {
 font-size: 16px;
 font-family: Arial, sans-serif;
}

h2.subtitle {
  text-align: center }

h3 {
 font-size: 12px;
 font-family: Arial, sans-serif;
}

hr {
  width: 75% }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.line-block {
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em ;
  background-color: #eeeeee;
  border-color: #000000;
  border-width: thin; 
  font-size: 14px
}

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.option-argument {
  font-style: italic }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

table {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.citation {
  border-left: solid thin gray ;
  padding-left: 0.5ex }

table.docinfo {
  margin: 2em 4em;
}

table.footnote {
  border-left: solid thin black ;
  padding-left: 0.5ex }

td, th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

th.docinfo-name, th.field-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap;
  }

h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
  font-size: 100% }

tt {}

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document" id="serial-communication">
<h1 class="title">Serial Communication</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr class="field"><th class="docinfo-name">TEP:</th><td class="field-body">113</td>
</tr>
<tr class="field"><th class="docinfo-name">Group:</th><td class="field-body">Core Working Group</td>
</tr>
<tr class="field"><th class="docinfo-name">Type:</th><td class="field-body">Documentary</td>
</tr>
<tr><th class="docinfo-name">Status:</th>
<td>Final</td></tr>
<tr class="field"><th class="docinfo-name">TinyOS-Version:</th><td class="field-body">2.x</td>
</tr>
<tr><th class="docinfo-name">Author:</th>
<td>Ben Greenstein and Philip Levis</td></tr>
</tbody>
</table>
<div class="note">
<p class="first admonition-title">Note</p>
<p class="last">This memo documents a part of TinyOS for the TinyOS Community, and
requests discussion and suggestions for improvements.  Distribution
of this memo is unlimited. This memo is in full compliance with
TEP 1.</p>
</div>
<div class="section">
<h1><a id="abstract" name="abstract">Abstract</a></h1>
<p>This memo describes the structure and standard implementation of the
TinyOS 2.x serial communication system for mote-to-PC data
exchange. The system is broken into three levels (encoding, framing,
and dispatch) to allow easy experimentation and replacement. It can
also handle multiple packet formats: unlike 1.x, 2.x serial packets
are not bound to the mote's radio packet format. Additionally, one of
the supported packet formats is platform independent, so PC-side
applications can communicate with arbitrary motes.</p>
</div>
<div class="section">
<h1><a id="introduction" name="introduction">1. Introduction</a></h1>
<p>Users need to read data out of a TinyOS network. The most common
approach is to attach a mote to a PC or laptop with a wired
connection. While the interface on the PC side can vary from a serial
cable to a USB device to IP, the mote generally talks to a serial port
(UART). In TinyOS 1.x, the UART packet format is platform-specific,
pushing a good deal of complexity into the protocol and PC-side tools
in order to discover and properly handle platform diversity. TinyOS
2.0 introduces the notion of packet format dispatch, so a mote can
support multiple UART packet formats simultaneously.  This allows
transparent bridging (e.g., an 802.15.4 base station) to exist in
parallel with platform-independent communication, which simplifies the
PC toolchain. This memo documents the protocols and structure of the
TinyOS 2.x serial communication stack.</p>
</div>
<div class="section">
<h1><a id="serial-stack-structure" name="serial-stack-structure">2. Serial Stack Structure</a></h1>
<p>The TinyOS 2.x serial communication stack is broken up into four
functional components. From bottom to top, they are</p>
<blockquote>
<p>o the raw UART,</p>
<p>o the encoder/framer,</p>
<p>o the protocol,</p>
<p>o and the dispatcher.</p>
</blockquote>
<p>Structurally, they look like this:</p>
<pre class="literal-block">
 _____________________
|                     |
|     Dispatcher      |       Packet formatting.
|_____________________|
 _____________________
|                     |
|      Protocol       |       Acknowledgements, CRC computation,
|_____________________|       windowing.
 _____________________
|                     |
|    Encoder/Framer   |       Translating raw bytes into frame
|_____________________|       delimiters, escape bytes.
 _____________________
|                     |
|      Raw UART       |       Platform code for reading/writing
|_____________________|       bytes over the serial connection.
</pre>
<p>The bottom three provide a byte-level interface: only the Dispatcher
provides a packet-level interface. The top three are all
platform-independent: only the UART is platform-specific code.</p>
<p>The lowest level of the stack is the raw UART. This HIL component
provides functionality for configuring the UART (speed, stop bytes,
etc.), sending/receiving bytes, and flushing the UART.</p>
<p>The Encoder/Framer sits above the raw UART. This component translates
raw data bytes into packet bytes using a serial protocol's
encoding. The Encoder/Framer assumes that a protocol's encoding has
two kinds of bytes: delimiters and data bytes, and signals each in
separate events to the component above.</p>
<p>The Protocol component handles data and delimiter byte events. It is
responsible for reading in and sending all protocol control
packets. If the Protocol component starts receiving a data packet, it
signals to the Dispatcher that a packet has started and signals the
data bytes. When the data packet completes, the Protocol signals to
the Dispatcher that the packet is complete and whether it passed the
protocol-level CRC.</p>
<p>The Dispatcher component handles data packet bytes and delimiters. It
is responsible for reading data bytes into a message_t and signaling
packet reception to components above it. The dispatcher can support
multiple packet formats. Based on how message_t works (see TEP
111[<a class="reference" href="#tep111">tep111</a>]), this boils down to knowing where in a message_t a
particular packet format begins (based on its header size). Section
3.4 describes how the default TinyOS 2.x implementation,
<tt class="docutils literal"><span class="pre">SerialDispatcherC</span></tt> does this.</p>
</div>
<div class="section">
<h1><a id="the-2-x-serial-stack-implementation" name="the-2-x-serial-stack-implementation">3. The 2.x Serial Stack Implementation</a></h1>
<p>Section 2 describes the basic structure of the TinyOS 2.x serial
stack. This section describes its actual implementation,
including SerialActiveMessageC, which sits on top of the Dispatcher.
All of the components except for UartC are part of the serial
library that lives in <tt class="docutils literal"><span class="pre">tos/lib/serial</span></tt>.</p>
<div class="section">
<h2><a id="raw-uart-uartc" name="raw-uart-uartc">3.1 Raw UART: UartC</a></h2>
<p>The UART HIL[<a class="reference" href="#tep2">TEP2</a>] is <tt class="docutils literal"><span class="pre">UartC</span></tt>, which provides a byte-level
interface to the underlying serial communication. It provides the
<tt class="docutils literal"><span class="pre">SerialByteComm</span></tt> interface:</p>
<pre class="literal-block">
interface SerialByteComm {
  async command error_t put(uint8_t data);
  async event void get(uint8_t data);
  async event void putDone();
}
</pre>
<p>Alternatively, <tt class="docutils literal"><span class="pre">UartC</span></tt> may provide the UartStream multi-byte level
interface. See the Low-Level I/O TEP [<a class="reference" href="#tep117">TEP117</a>] for details.</p>
<p>Additionally, UartC provides a split-phase interface to signal when
the UART is idle. There are situations (such as when powering down the
usart, when switching from TX to RX on a radio with a UART data line,
etc.) when we need explicit information that the data sent over the
UART has actually been transmitted in full. The problem is that on
MCUs that double-buffer UART communication (such as the msp430), a
putDone event signifies that the UART is ready to accept another byte,
but NOT that the UART is idle.</p>
<pre class="literal-block">
interface SerialFlush {
  command void flush();
  event void flushDone();
}
</pre>
<p>It may provide additional interfaces for configuring the serial
port. This TEP does not consider this topic.</p>
</div>
<div class="section">
<h2><a id="encoder-framer-hdlctranslatec" name="encoder-framer-hdlctranslatec">3.2 Encoder/Framer: HdlcTranslateC</a></h2>
<p>HdlcTranslateC is the serial encoder/framer. It uses the
<tt class="docutils literal"><span class="pre">SerialByteComm</span></tt> interface and provides the <tt class="docutils literal"><span class="pre">SerialFrameComm</span></tt>
interface:</p>
<pre class="literal-block">
interface SerialFrameComm {
  async command error_t putDelimiter();
  async command error_t putData(uint8_t data);
  async command void resetSend();
  async command void resetReceive();
  async event void delimiterReceived();
  async event void dataReceived(uint8_t data);
  async event void putDone();
}
</pre>
<p>As its name suggests, it uses the same encoding as the HDLC[<a class="reference" href="#hdlc">HDLC</a>]
protocol. <tt class="docutils literal"><span class="pre">0x7e</span></tt> is reserved as a frame delimiter byte, and <tt class="docutils literal"><span class="pre">0x7d</span></tt>
is reserved as an escape byte. HdlcTranslateC maintains ten bits of
state. The receive and send paths each have one bit to store whether
they are using an escape byte, and the transmit path has a byte for
when it sends an escaped byte.</p>
<p>When HdlcTranslateC receives a delimiter byte, it signals
delimiterReceived(). When HdlcTranslateC receives an escape byte, it
sets the receiveEscape flag to true. When it receives any other byte,
it tests to see if the receiveEscape flag is set; if so, it XORs the
data byte with <tt class="docutils literal"><span class="pre">0x20</span></tt> and clears the flag. It signals dataReceived()
with the byte. The most common use of escape byte is to transmit data
bytes corresponding to the delimiter byte or escape byte. For example,
<tt class="docutils literal"><span class="pre">0x7e</span></tt> becomes <tt class="docutils literal"><span class="pre">0x7d</span> <span class="pre">0x5e</span></tt>.</p>
<p>HdlcTranslateC performs similar actions on the transmit side. When
told to transmit the delimiter or escape byte as a data byte, it sets
the transmitEscape flag to true, stores the data byte XOR <tt class="docutils literal"><span class="pre">0x20</span></tt>,
and sends an escape byte. When the escape byte is sent, it sends the
stored data byte.</p>
</div>
<div class="section">
<h2><a id="protocol-serialp" name="protocol-serialp">3.3 Protocol: SerialP</a></h2>
<p>The SerialP component implements the serial protocol using PPP/HDLC-
like framing (See RFC 1662[<a class="reference" href="#rfc1662">RFC1662</a>]). Type dispatch and buffer
management are left to higher layers in the serial stack. The protocol
is currently stop-and-wait in the host-to-mote direction and best
effort in the mote-to-host direction.</p>
<p>SerialP provides two byte-level interfaces to the upper layer for
sending and receiving packets, respectively called SendBytePacket and
ReceiveBytePacket.</p>
<p>On the sending side, SerialP is responsible for encapsulation of upper
layer packets. An upper layer component such as SerialDispatcherC
initiates the sending of a packet by calling startSend(), passing the
first byte to send. SerialP collects subsequent bytes by signalling
nextByte(). Within the nextByte handler or between calls to nextByte(),
the upper layer should indicate the end-of-packet by calling
completeSend(). If completeSend is called from within a nextByte()
handler, SerialP will ignore the return of the call to nextByte().</p>
<pre class="literal-block">
interface SendBytePacket {
  async command error_t startSend(uint8_t first_byte);
  async command error_t completeSend();
  async event uint8_t nextByte();
  async event void sendCompleted(error_t error);
}
</pre>
<p>SerialP maintains a small window of bytes that have been received by
the upper layer and not yet sent to the UART. Depending on the timing
requirements of the underlying UART, the size of this window can be
changed.  SerialP uses repeated calls to nextByte() to keep this window
filled.</p>
<p>SerialP uses SerialFrameComm to send a delimiter between frames, a
serial-level type field, the bytes of the packet, and a two-byte frame
CRC. For mote-to-host gap detection and link reliability, a sequence
number may also be sent (not activated in the default implementation).</p>
<p>After sending an entire frame and receiving the last putDone() event
from below, SerialP signals sendCompleted() to indicate the success or
failure of a requested transmission.</p>
<p>Packet reception is also managed by SerialP and the interface
provided to the upper layer is ReceiveBytePacket:</p>
<pre class="literal-block">
interface ReceiveBytePacket {
  async event error_t startPacket();
  async event void byteReceived(uint8_t b);
  async event void endPacket(error_t result);
}
</pre>
<p>Upon receiving an interframe delimiter and a new frame's header,
SerialP signals the upper layer indicating that a packet is
arriving. For each byte received, SerialP signals byteReceived().
Once SerialP receives the complete frame it signals endPacket with a
value of SUCCESS. If instead it loses sync during reception it signals
endPacket with FAIL.</p>
<p>SerialP acknowledges frames it receives. Acknowledgements have a
higher priority than data transmissions and consequently, data frames
may be slightly delayed. However, acknowledgement information is
stored in a queue separate from the data buffer, so a data packet to
be transmitted may begin spooling into SerialP while SerialP is
actively sending an acknowledgement.</p>
<p>Only the PC-to-mote communication path supports acknowledgements.
SerialP does not request acknowledgements from the PC for two reasons.
First, acks are not perfect reliable: they are used on the
PC-to-mote path to raise reliability to a usable level. In the case of
the PC-to-mote path, the UART receive buffer is typically a single
byte, so a high interrupt load can easily lose (and sometimes does) a
byte. This is in contrast to the PC receive buffer, which is much
larger and does not have to deal with overflow. Second, adding support
for acks would increase the code size and complexity of the serial
stack. As code space is often at a premium, this would add little
needed functionality at significant cost. Of course, any application
that requires perfect reliability may layer its own scheme on top of
the serial protocol.</p>
<p>The acknowledgement protocol is stop-and-wait to minimize buffering on
the mote side. This is considered more important on memory constrained
devices than increased throughput in the PC-to-mote direction, which
most applications only use for occasional control transmissions.</p>
</div>
<div class="section">
<h2><a id="dispatcher-serialdispatcherc" name="dispatcher-serialdispatcherc">3.4 Dispatcher: SerialDispatcherC</a></h2>
<p>SerialDispatcherC handles the data packets that the Protocol component
receives. It uses the SendBytePacket and ReceiveBytePacket interfaces,
and provides parameterized Send and Receive interfaces. The parameter
in the Send and Receive interfaces (<tt class="docutils literal"><span class="pre">uart_id_t</span></tt>) determines the
packet format contained in the message_t.</p>
<p>SerialDispatcherC places a one-byte header, the packet format
identifier, on the packets sent and received through SerialP.
SerialDispatcherC uses a parameterized SerialPacketInfo interface to
be able to handle various packet formats:</p>
<pre class="literal-block">
interface SerialPacketInfo {
  async command uint8_t offset();
  async command uint8_t dataLinkLength(message_t* msg, uint8_t upperLen);
  async command uint8_t upperLength(message_t* msg, uint8_t dataLinkLen);
}
</pre>
<p>When SerialDispatcherC receives the first data byte of a packet from
SerialP, it stores it as the packet type and calls
offset() to determine where in a message_t that
packet format begins. It then spools data bytes in, filling them into
its message_t buffer. Similarly, on the send side, it first sends the
type byte and spools out data bytes starting from the index denoted by
the call to offset(). SerialDispatcherC uses the two length commands,
dataLinkLength() and upperLength(), to translate between the two notions
of packet length: above, length refers to the payload excluding
header, while below it refers to the payload plus header.</p>
<p>A component that provides communication over the serial port with
uart_id_t <em>U</em> MUST wire a component implementing SerialPacketInfo to
SerialDispatcherC with uart_id_t <em>U</em>. The file <tt class="docutils literal"><span class="pre">Serial.h</span></tt> contains
reserved uart_id_t's for supported packet formats. Currently, only
platform independent active messages
(<tt class="docutils literal"><span class="pre">TOS_SERIAL_ACTIVE_MESSAGE_ID</span></tt>, described in Section 3.5), 802.15.4
active messages (<tt class="docutils literal"><span class="pre">TOS_SERIAL_802_15_4_ID</span></tt>), mica2 CC1000 packets
(<tt class="docutils literal"><span class="pre">TOS_SERIAL_CC1000_ID</span></tt>) and the error code
<tt class="docutils literal"><span class="pre">TOS_SERIAL_UNKNOWN_ID</span></tt> are reserved. New packet formats MUST NOT
reuse any reserved identifiers.</p>
</div>
<div class="section">
<h2><a id="serialactivemessagec" name="serialactivemessagec">3.5 SerialActiveMessageC</a></h2>
<p>SerialActiveMessageC is a platform-independent active message layer
that operates on top of the serial communication
stack. SerialActiveMessageC is a configuration that wires
SerialActiveMessageP to SerialDispatcherC with uart_id_t
TOS_SERIAL_ACTIVE_MESSAGE_ID and wires SerialPacketInfoActiveMessageP
to SerialDispatcherC with uart_id_t TOS_SERIAL_ACTIVE_MESSAGE_ID:</p>
<pre class="literal-block">
includes Serial;``
configuration SerialActiveMessageC {
  provides {
    interface Init;
    interface AMSend[am_id_t id];
    interface Receive[am_id_t id];
    interface Packet;
    interface AMPacket;
  }
  uses interface Leds;
}
implementation {
  components new SerialActiveMessageP() as AM, SerialDispatcherC;
  components SerialPacketInfoActiveMessageP as Info;

  Init = SerialDispatcherC;
  Leds = SerialDispatcherC;

  AMSend = AM;
  Receive = AM;
  Packet = AM;
  AMPacket = AM;

  AM.SubSend -&gt; SerialDispatcherC.Send[TOS_SERIAL_ACTIVE_MESSAGE_ID];
  AM.SubReceive -&gt; SerialDispatcherC.Receive[TOS_SERIAL_ACTIVE_MESSAGE_ID];

  SerialDispatcherC.SerialPacketInfo[TOS_SERIAL_ACTIVE_MESSAGE_ID] -&gt; Info;
}
</pre>
<p>SerialActiveMessageP is a generic component so that it can be used to
sit on top of any packet-level communication layer. It does not filter
packets based on destination address or group. It assumes that if the
packet was received over the serial port, it was destined to the
node. This saves PC-side tools from having to discover or consider the
ID and group of a mote.</p>
<p>Platform-independent active messages do not have a CRC (they assumes
the serial stack CRC is sufficient), and have the following header:</p>
<pre class="literal-block">
typedef nx_struct SerialAMHeader {
  nx_am_addr_t addr;
  nx_uint8_t length;
  nx_am_group_t group;
  nx_am_id_t type;
} SerialAMHeader;
</pre>
</div>
<div class="section">
<h2><a id="packet-format" name="packet-format">3.6 Packet Format</a></h2>
<p>A data packet in the TinyOS 2.x serial stack has the following format
over the wire. Each protocol field is associated with a specific component:</p>
<pre class="literal-block">
   ____________________________________________
  | | | | |                               |  | |
  | | | | |                               |  | |
  |_|_|_|_|_______________________________|__|_|
   F P S D         Payload                 CR F

F       = Framing byte, denoting start of packet: HdlcTranslateC
P       = Protocol byte: SerialP
S       = Sequence number byte: SerialP
D       = Packet format dispatch byte: SerialDispatcherC
Payload = Data payload (stored in SerialDispatcherC): SerialDispatcherC
CR      = Two-byte CRC over S to end of Payload: SerialP
F       = Framing byte denoting end of packet: HdlcTranslateC
</pre>
<p>Payload is a contiguous packet that SerialDispatcherC reads in.  Note
that any data bytes (P - CR) equal to 0x7e or 0x7d will be escaped to
0x7d 0x5e or 0x7d 0x5d accordingly. For example, a platform
independent AM packet of type 6, group 0x7d, and length 5 to
destination 0xbeef with a payload of 1 2 3 4 5 would look like this:</p>
<p><tt class="docutils literal"><span class="pre">7e</span> <span class="pre">40</span> <span class="pre">09</span> <span class="pre">00</span> <span class="pre">be</span> <span class="pre">ef</span> <span class="pre">05</span> <span class="pre">7d</span> <span class="pre">5d</span> <span class="pre">06</span> <span class="pre">01</span> <span class="pre">02</span> <span class="pre">03</span> <span class="pre">04</span> <span class="pre">05</span> <span class="pre">7e</span></tt></p>
<p>Note that the group 0x7d is escaped to 0x7d 0x5d. The protocol field
(P) is 0x40 (64), corresponding to <tt class="docutils literal"><span class="pre">SERIAL_PROTO_ACK</span></tt> (in Serial.h).</p>
</div>
</div>
<div class="section">
<h1><a id="access-abstractions" name="access-abstractions">4. Access Abstractions</a></h1>
<p>Two generic components: SerialAMSenderC and SerialAMReceiverC connect
to SerialActiveMessageC to provide virtualized access to the serial
stack. Each instantiation of SerialAMSenderC has its own queue of
depth one. Therefore, it does not have to contend with other
SerialAMSender instantiations for queue space. The underlying
implementation schedulers the packets in these queues using some form
of fair-share queueing. SerialAMReceiverC provides the virtualized
abstraction for reception. These abstractions are very similar to
TinyOS's radio abstractions, namely, AMSenderC and AMReceiverC. See
Section 4 of TEP 116[<a class="reference" href="#tep116">TEP116</a>] for more information. Unlike the
services in the TEP 116, the serial component virtualizations provide
no snooping capabilities.</p>
</div>
<div class="section">
<h1><a id="author-s-address" name="author-s-address">5. Author's Address</a></h1>
<div class="line-block">
<div class="line">Philip Levis</div>
<div class="line">358 Gates</div>
<div class="line">Computer Science Laboratory</div>
<div class="line">Stanford University</div>
<div class="line">Stanford, CA 94305</div>
<div class="line"><br /></div>
<div class="line">phone - +1 650 725 9046</div>
<div class="line">email - <a class="reference" href="mailto:pal&#64;cs.stanford.edu">pal&#64;cs.stanford.edu</a></div>
<div class="line"><br /></div>
<div class="line"><br /></div>
<div class="line">Ben Greenstein</div>
<div class="line">Intel Research Seattle</div>
<div class="line">1100 NE 45th Street, 6th Floor</div>
<div class="line">Seattle, WA 98105</div>
<div class="line"><br /></div>
<div class="line">phone -  +1 206 206 545 2501</div>
<div class="line">email - <a class="reference" href="mailto:benjamin.m.greenstein&#64;intel.com">benjamin.m.greenstein&#64;intel.com</a></div>
</div>
</div>
<div class="section">
<h1><a id="citations" name="citations">6. Citations</a></h1>
<table class="docutils citation" frame="void" id="tep2" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep2">[TEP2]</a></td><td>TEP 2: Hardware Abstraction Architecture. tinyos-2.x/doc/txt/tep2.txt</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep111" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep111">[TEP111]</a></td><td>TEP 111: message_t. tinyos-2.x/doc/txt/tep111.txt</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep116" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep116">[TEP116]</a></td><td>TEP 116: Packet Protocols. tinyos-2.x/doc/txt/tep116.txt</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="tep117" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="tep117">[TEP117]</a></td><td>TEP 117: Low-Level I/O. tinyos-2.x/doc/txt/tep117.txt</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="hdlc" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="hdlc">[HDLC]</a></td><td>International Organization For Standardization, ISO Standard 3309-1979, &quot;Data communication - High-level data link control procedures - Frame structure&quot;, 1979.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="rfc1662" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a name="rfc1662">[RFC1662]</a></td><td>PPP in HDLC-like Framing, Internet Engineering Task Force (IETF), 1994</td></tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
